﻿/******************************************************
* author :  cwj
* email  :  chenwenji_360@live.com 
* history:  created by cwj 2015/7/16 16:12:40 
* clrversion :4.0.30319.18444
******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Machine.DataAccess.Common.ORM
{
    class PropertyInvoker<TTarget, TValue> : IPropertyInvoker
    {
        //private PropertyInfo propertyInfo;
        private Func<object, object> GetFunc;
        private Action<object, object> SetFunc;
        public PropertyInvoker(PropertyInfo info)
        {
            this.PropertyInfo = info;
            var setFuncTemp = Delegate.CreateDelegate(typeof(Action<TTarget, TValue>), PropertyInfo.GetSetMethod()) as Action<TTarget, TValue>;
            this.SetFunc = (target, value) =>
            {
                object realValue = value;
                if (this.PropertyInfo.PropertyType.IsEnum && value is string) realValue = Enum.Parse(this.PropertyInfo.PropertyType, value.ToString(), true);
                if (this.PropertyInfo.PropertyType.IsValueType && value == null) return;
                setFuncTemp((TTarget)target, (TValue)realValue);
            };
            var getFuncTemp = Delegate.CreateDelegate(typeof(Func<TTarget, TValue>), PropertyInfo.GetGetMethod()) as Func<TTarget, TValue>;
            this.GetFunc = (target) =>
            {
                return getFuncTemp((TTarget)target);
            };
        }

        public PropertyInfo PropertyInfo { get; private set; }

        public string PropertyName { get { return PropertyInfo.Name; } }

        public void SetValue(object target, object value)
        {
            this.SetFunc(target, value);
        }

        public object GetValue(object target)
        {
            return (TValue)this.GetFunc(target);
        }
    }
}
